package com.itguigu.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 配置类：解决第三方bean要使用xml方式配置的问题
 *
 *步骤：
 *    1.@ComponmentScan({"路径1","路径2"}) 包扫描注解配置类，替代<context:component-scan base-package="com.itguigu"/>
 *    2.引入外部配置文件注解  代替<context:property-placeholder location="classpath:db.properties"/>
 *    3.声明第三方依赖的bean组件 代替<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">....
 */
@Configuration//配置类
@ComponentScan({"com.itguigu"}) // 包扫描注解
@PropertySource("classpath:jdbc.properties") // 引入外部配置文件注解
public class JavaConfiguration {
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;


    /**
     * 相当于xml中<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">.....
     *
     * @Bean ->一个方法
     *
     * 方法的返回值==bean组件的类型或者他的接口和父类（DruidDataSource）
     * 方法的名称为bean组件的id
     *
     * 方法体可以自定义实现过程
     * 最重要一步！ @Bean会真正的注册bean组件 存储到spring容器中
     *
     * 问题一：beanName的问题
     *       默认：beanName为方法名
     *       指定：可以通过@Bean(name="dataSource")指定beanName
     *
     * 问题二：周期方法如何指定
     *       原有注解方案: @PostConstruct @PreDestroy
     *       Spring注解方案： @Bean(initMethod="init",destroyMethod="close")
     *
     * 问题三：作用域Scope
     *       和以前还是使用@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) 默认单例
     *
     * 问题四：如何引用其他的ioc bean
     *        直接调用对方的bean
     *        直接形参变量进行引入，要求对方bean已经注册 如果有多个形参名 == 组件id
     */
    @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
    @Bean("goudan")
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DruidDataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }


}
